import decodeGif from 'decode-gif'
function colorAdd(color, color2) {
  const oa = color[3] / 255
  const ca = color2[3] / 255
  const or = color[0] * oa * (1 - ca)
  const og = color[1] * oa * (1 - ca)
  const ob = color[2] * oa * (1 - ca)
  const cr = color2[0] * ca
  const cg = color2[1] * ca
  const cb = color2[2] * ca
  const rgba = [
    or + cr,
    og + cg,
    ob + cb,
    color2[3] == 0 ? color[3] : color2[3],
  ]
  return rgba.map((v) => Math.min(255, Math.max(0, Math.round(v))))
}
const fileToBuffer = async (file: File) => {
  return new Promise<ArrayBuffer>((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      resolve
        ? resolve(e.target.result as ArrayBuffer)
        : reject(new Error('Failed to read file'))
    }
    reader.onerror = reject
    reader.readAsArrayBuffer(file)
  })
}
function setImageData(imageData: ImageData, data: Uint8ClampedArray) {
  for (let i = 0; i < imageData.data.length; i += 4) {
    const now = colorAdd(
      imageData.data.subarray(i, i + 4),
      data.subarray(i, i + 4)
    )
    imageData.data.set(now, i)
  }
}
export interface GifResult {
  frames: string[]
  width: number
  height: number
  duration: number
}
export async function processGIF(file: File): Promise<GifResult> {
  const buffer = await fileToBuffer(file)
  const result = decodeGif(new Uint8Array(buffer))
  const canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')
  canvas.width = result.width
  canvas.height = result.height
  const imageData = ctx.createImageData(result.width, result.height)
  const frames = result.frames.map((frame) => {
    setImageData(imageData, frame.data)
    ctx.putImageData(imageData, 0, 0)
    const url = canvas.toDataURL('image/png')
    return url
  })
  return {
    frames,
    width: result.width,
    height: result.height,
    duration: result.frames[1].timeCode,
  }
}
